package thesis.filesharing.web.validator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import thesis.filesharing.bo.GroupBO;
import thesis.filesharing.bo.StudentBO;
import thesis.filesharing.model.Group;
import thesis.filesharing.model.Student;
import thesis.filesharing.resources.Constants;
import thesis.filesharing.web.auth.AuthUtil;
import thesis.filesharing.web.viewmodel.RegisterGroupViewModel;

import com.google.appengine.api.datastore.KeyFactory;

public class UpdateRegisterGroupValidator implements Validator {
	
	@Autowired
	private StudentBO studentBO;
	
	@Autowired
	private GroupBO groupBO;
	
	@Override
	public boolean supports(Class<?> clazz) {
		return UpdateRegisterGroupValidator.class.isAssignableFrom(clazz);
	}

	@Override
	public void validate(Object target, Errors errors) {
		RegisterGroupViewModel model = (RegisterGroupViewModel) target;
		if (model.getClassKey() == null || "NONE".equalsIgnoreCase(model.getClassKey())) {
			errors.rejectValue("classKey", "classKey.required");
			return;
		}
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "studentIds", "studentIds.required");
		if (model.getStudentIds() != null && !"".equals(model.getStudentIds().trim())) {
			String studentIdStr = model.getStudentIds().trim().replace(" ", "");
			String[] studentIds = studentIdStr.split(",");
			
			// Check if studentIds are valid formats
			Pattern studentIdPattern = Pattern.compile(Constants.STUDENT_ID_PATTERN);
			Matcher studentIdMatcher = null;
			
			for (String studentId : studentIds) {
				studentIdMatcher = studentIdPattern.matcher(studentId);
				if (!studentIdMatcher.matches()) {
					errors.reject("studentId.incorrectFormat");
					return;
				}
			}
			
			// Check if student has studentId has registered class
			StringBuilder builder = new StringBuilder();
			for (String studentId : studentIds) {
				if (!studentBO.checkStudentRegisteredClass(studentId, model.getClassKey())) {
					builder.append(studentId).append(", ");
				}
			}
			if (builder.length() > 0) {
				String msg = builder.substring(0, builder.length() - 2);
				errors.reject("studentId.notExisted", new Object[] { msg }, msg + " is/are not existed");
				return;
			}
			
			// Check if there is any studentId registered in other groups
			String currentStudentId = AuthUtil.getCurrentAuthenticatedUsername();
			Student currentStudent = studentBO.findStudentById(currentStudentId);
			if (currentStudent != null) {
				Group currentGroup = groupBO.findGroupStudentRegisteredInClass(currentStudent.getStudentKey(), model.getClassKey());
				if (currentGroup != null) {
					for (String studentId : studentIds) {
						Student s = studentBO.findStudentById(studentId);
						if (groupBO.checkStudentRegisteredInOtherGroup(s.getStudentKey(), KeyFactory.stringToKey(model.getClassKey()), currentGroup.getGroupKey())) {
							builder.append(studentId).append(", ");
						}
					}
					if (builder.length() > 0) {
						String err = builder.substring(0, builder.length() - 2);
						errors.reject("studentId.existInOtherGroup", new Object[] { err }, err + " is/are already existed in other groups");
						return;
					}
				}
			}
		}
	}
}
